package rs.fon.is.music.parser;

import java.io.IOException;
import java.net.URI;
import java.util.LinkedList;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import rs.fon.is.music.domain.MusicAlbum;
import rs.fon.is.music.domain.MusicRecording;
import rs.fon.is.music.parser.exceptions.MusicAlbumNotFoundException;
import rs.fon.is.music.persistence.DataModelManager;
import rs.fon.is.music.util.URIGenerator;

public class MusicAlbumParser implements DomainClassParser<MusicAlbum>, Runnable {
	
	String urlAlbum;
	int numTracks;
	MusicAlbum album;
	
	public MusicAlbumParser(String url, int numTracks ) {
		this.urlAlbum = url;
		this.numTracks = numTracks;
	}

	@Override
	public MusicAlbum parse(String url) {

		Document doc;
		try {
			doc = Jsoup.connect(url).get();

			Elements albumElements = doc.getElementsByAttributeValue("itemtype","http://schema.org/MusicAlbum");

			
			if (albumElements.size() > 0) {
	
				MusicAlbum album = new MusicAlbum();
	
				Element albumElement = albumElements.first();
	
				// URI
				album.setUri(URIGenerator.generate(album));
	
				// URL
				album.setUrl(new URI(url));
	
				// name
				if (albumElement.getElementsByAttributeValue("itemprop", "name").size() > 0)
					album.setName(albumElement.getElementsByAttributeValue("itemprop", "name").first().text());
	
				// image
				if (albumElement.getElementsByAttributeValue("itemprop", "image").size() > 0)
					album.setImage(new URI(albumElement.getElementsByAttributeValue("itemprop", "image").first().attr("src")));
	
				// interactionCount
				if (albumElement.getElementsByAttributeValue("itemprop", "interactionCount").size() > 0)
					album.setInteractionCount(albumElement.getElementsByAttributeValue("itemprop","interactionCount").first().attr("content"));
	
				// keywords
				if (albumElement.getElementsByAttributeValue("itemprop", "keywords").size() > 0){
					String keywordsString = albumElement.getElementsByAttributeValue("itemprop", "keywords").first().attr("content");
					String [] keywords = keywordsString.split(",");
					for (String keyword : keywords) {
						album.addKeyword(keyword.trim());
					}
				}
					
	
				// numTracks
				album.setNumTracks(numTracks);
				
				// tracks
				album.setTracks(parseRecordings(url));
	
				DataModelManager.getInstance().save(album);
				
				return album;
	
			} else
				
				throw new MusicAlbumNotFoundException("schema:MusicAlbum instance is not found on this URL.");
		
		} catch (IOException e) {
			return parse(urlAlbum);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

	}

	public LinkedList<MusicRecording> parseRecordings(String url){

		Document doc;
		
		try {
			doc = Jsoup.connect(url).get();
			
			LinkedList<MusicRecording> recordings = new LinkedList<>();

			Elements recordingElements = doc.getElementsByAttributeValue("itemtype","http://schema.org/MusicRecording");

			MusicRecordingParser recordingParser = new MusicRecordingParser();

			String noHttp = url.substring(7, url.length());

			String domain = noHttp.substring(0, noHttp.indexOf('/'));

			for (Element recordingElement : recordingElements) {

				String recordingURL = recordingElement.getElementsByAttributeValue("itemprop", "url").first().attr("content");

				if (!recordingURL.startsWith("http://" + domain))
					recordingURL = "http://" + domain + recordingURL;

				MusicRecording musicRecording = recordingParser.parse(recordingURL);
				if(musicRecording != null)
					recordings.add(musicRecording);
			}

			return recordings;
			
		} catch (IOException e) {
			return parseRecordings(url);
		}
	}

	@Override
	public void run() {
		
		try {

			System.out.println("Executing : " + urlAlbum);
			setAlbum(parse(urlAlbum));
					
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	public String getUrlAlbum() {
		return urlAlbum;
	}

	public void setUrlAlbum(String urlAlbum) {
		this.urlAlbum = urlAlbum;
	}

	public int getNumTracks() {
		return numTracks;
	}

	public void setNumTracks(int numTracks) {
		this.numTracks = numTracks;
	}

	public MusicAlbum getAlbum() {
		return album;
	}

	public void setAlbum(MusicAlbum album) {
		this.album = album;
	}
	
	

}
